package com.nextbus.ui;


import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.nextbus.model.Prediction;
import com.nextbus.model.RouteConfig;
import com.nextbus.model.Stop;
import com.nextbus.model.VehicleLocationsData;

/**
 * 这里的设计是事先吧Busoverlay添加到mapview里面，后面的操作不重复添加了，只是更新
 * busoverlay里面的overlayitems数据并且使得mapview重绘
 * 
 * 要注意一点，mapview里面添加了两个Busoverlay对象，一个车，一个站点，所以在刷新数据之前要使得另一个对象在图中消失
 * @author dxt
 *
 */
public class BusOverlay extends BalloonItemizedOverlay<BusOverlayItem>{
	
	public static final int NOT_SELECTED = -1;
	private ArrayList<BusOverlayItem> overlayItems = new ArrayList<BusOverlayItem>();
	private Context context;
	private MapView mapView;
	private float density;
	private int viewMode;
	private Drawable busDrawable;
	private Drawable arrowDrawable;
	private ArrayList<Integer>heading=new ArrayList<Integer>();
	//当融合车和箭头的时候在draw里面判断，只要需要融合的时候才给overlaitem添加图片，其他populate就不会引起错误了
	private boolean MergerBusArrow=false;
	
 	public BusOverlay(Drawable defaultMarker, MapView mapView, Context context,int viewMode) {
		super(boundCenterBottom(defaultMarker), mapView);
		this.context = context;
		this.mapView=mapView;

		this.viewMode=viewMode;
		this.setOnFocusChangeListener(new OnFocusChangeListener() {
			//如果点击的焦点变化了之后，就进入这个函数
			@Override
			public void onFocusChanged(ItemizedOverlay overlay,OverlayItem newFocus) {
				//dxt 	点击空白的地方的时候，焦点发生变化，应该使得原来的弹出框消失
				//		当然，如果点击正常的车的时候，就会正常画出弹出框				
				setLastFocusedIndex(NOT_SELECTED);
				setFocus((BusOverlayItem)newFocus);
				if (newFocus == null)
				{
					hideBalloon();//点击的一个地方看看会不会有这个OverlayItem，如果没有就把提示框消失掉
				}
			}
		});	
		//Return the intrinsic height of the underlying drawable object.
		setBalloonBottomOffset(defaultMarker.getIntrinsicHeight() + 4);
		populate();
	}
 	public BusOverlay(Drawable defaultMarker, MapView mapView, Context context,int viewMode,Drawable arrow) {
		super(boundCenterBottom(defaultMarker), mapView);
		this.context = context;
		this.mapView=mapView;
		this.busDrawable=defaultMarker;
		this.arrowDrawable=arrow;
		this.viewMode=viewMode;
		
		populate();
		this.setOnFocusChangeListener(new OnFocusChangeListener() {
			//如果点击的焦点变化了之后，就进入这个函数
			@Override
			public void onFocusChanged(ItemizedOverlay overlay,OverlayItem newFocus) {
				setLastFocusedIndex(NOT_SELECTED);
				setFocus((BusOverlayItem)newFocus);
				if (newFocus == null)
				{
					hideBalloon();//点击的一个地方看看会不会有这个OverlayItem，如果没有就把提示框消失掉
				}
			}
		});	
		//得到高度，调整弹出框的位置
		setBalloonBottomOffset(defaultMarker.getIntrinsicHeight() + 4);
		populate();
	}

 	
	Location location;
	public void setLocation(Location location){
		this.location=location;
	}
	
	@Override
	protected BusOverlayItem createItem(int i) {
		// TODO Auto-generated method stub
		if (0==overlayItems.size()) {
			Toast.makeText(context, "当前没有数据啊", Toast.LENGTH_LONG);
			return null;
		}
		else{
			return (BusOverlayItem) overlayItems.get(i);
		}
	}

	@Override
	public int size() {
		// TODO Auto-generated method stub
		return overlayItems.size();
	}
	
	//点击之后的要显示一个弹出框(修改的入口)
	@Override
	protected boolean onTap(int index) {
		super.onTap(index);
		return true;
	}
	
	//这里生成的就是一个  balloonView对象
	protected BalloonoverLayView<BusOverlayItem> createBalloonOverlayView() {
		//调用父类的getmapview，获得mapview，然后返回this
		//sb保存了要显示snippet的信息，在这里传到BalloonoverlayView中
		BusPopupView view = new BusPopupView(getMapView().getContext(),getBalloonBottomOffset(),density);
		return view;
	}


	   
	public int getViewMode() {
		return viewMode;
	}

	public void setViewMode(int viewMode) {
		this.viewMode = viewMode;
	}
		
    public void  populateStopList(RouteConfig routeConfig){
    	if (routeConfig != null) {
            // 清除原先的数据
            if (overlayItems != null) {
                overlayItems.clear();
                overlayItems = null;
            }
            // 填充新获得的数据
            overlayItems = new ArrayList<BusOverlayItem>();
            ArrayList<Stop>stopList=routeConfig.getStops();
         //   System.out.println("stop站点的个数"+routeConfig.getStops().size());
            GeoPoint gp=null;
            for (Stop stop : stopList) {
                gp = new GeoPoint(
                        (int) (Double.parseDouble(stop.getLat()) * 1E6),
                        (int) (Double.parseDouble(stop.getLon()) * 1E6));
                StringBuilder sb=new StringBuilder();
                if(stop.getPredictions()!=null)
                {
	                ArrayList<Prediction>predictions = stop.getPredictions();    
	                for (Prediction prediction : predictions) {
						sb.append(prediction.getSpinner());
					}
                }
                overlayItems.add(new BusOverlayItem(gp, stop.getTitle(),sb.toString()));
            }
            // 重画公交车图标
            mapView.getController().animateTo(gp);
            populate();
        } else {
            Toast.makeText(context, "没有更新的stop信息", Toast.LENGTH_LONG).show();
        }
    }
	   
    public void populateBusPrediction(ArrayList<VehicleLocationsData> vehicles) {
    	System.out.println("现在路上的车的数量是        "+vehicles.size());
    	if (vehicles != null && vehicles.size() > 0) {
            // 清除原先的数据
            if (overlayItems != null) {
                overlayItems.clear();
                overlayItems = null;
            }
            // 填充新获得的数据
            overlayItems = new ArrayList<BusOverlayItem>();
            
            boolean mark=true;
            GeoPoint point=null;
            int lat = 0;
            int lon = 0;            
            for (VehicleLocationsData vehicle : vehicles) {
            	mark = false; 
                lat = (int) (Double.parseDouble(vehicle.getLat()) * 1E6);
            	lon = (int) (Double.parseDouble(vehicle.getLon()) * 1E6);
            	
                point = new GeoPoint(lat, lon);	   
                StringBuffer vehicleSpinnet=vehicle.getSpinnet();
                BusOverlayItem overlayitem = new BusOverlayItem(point,
                							vehicle.getRouteTag()+"\n"+vehicle.getDirTag()+ "\n",
                							vehicleSpinnet.toString());
                //存储每个车的朝向，画箭头的时候要用
                //dxt  这里要注意下，朝向有0.0的值，所以朝向要先转化为double，再转化为int
                heading.add((int) Double.parseDouble(vehicle.getHeading()));
                System.out.println("测试车的指向    "+vehicle.getHeading());
                overlayItems.add(overlayitem);	               
            }
            if (mark) {
				Toast.makeText(context, "这条路线的其他方向上有车，这个方向上暂时没有，请稍后再试", Toast.LENGTH_LONG);
			}
            mapView.getController().animateTo(point);
            MergerBusArrow=true;
            populate();	           
        } else {
            Toast.makeText(context, "没有更新的bus信息", Toast.LENGTH_LONG).show();
        }
    }    
	    
    public ArrayList<BusOverlayItem> getOverlayItems() {
    	return overlayItems;
    }

    public void setOverlayItems(ArrayList<BusOverlayItem> overlayItems) {
        this.overlayItems = overlayItems;
        populate();
    }
    
    public void clearOverlay()
    {
    	 if (overlayItems != null) {
                overlayItems.clear();
                overlayItems=null;
            }
    }
    
    /**
     * dxt  
     * 当populate的时候会引起busoverlay的重绘
     * 而且这里设定了条件 ，只有当需要赋融合的图片时才给OverlayItem赋值，其他populate的操作不会有什么影响
     */
    @Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
    	if (MergerBusArrow) {
    		//图层项的影子我们就不画了
			shadow=false;
			if (shadow==false) {
				for (int i = 0; i < overlayItems.size(); i++) {
					OverlayItem item=overlayItems.get(i);
					//这个类是用来合并两个图像的
					Drawable drawable=new BusDrawable(busDrawable,arrowDrawable,heading.get(i));
					//为车子和箭头添加融合后的图片
					item.setMarker(drawable);
				}
			}
		}					
		super.draw(canvas, mapView, shadow);
	}
    
    public void hide() {
		hideBalloon();
	}
	 
}
